﻿namespace LastfmNet.Api
{
    using System;
    using System.Globalization;

    /// <summary>
    /// Last.fm API playlist methods
    /// </summary>
    public class PlaylistApi
    {
        /// <summary>
        /// Reference to the Lastfm host class
        /// </summary>
        private Lastfm lastfmApi;

        /// <summary>
        /// Initializes a new instance of the PlaylistApi class.
        /// </summary>
        /// <param name="lastfmApi">Reference to the Lastfm host class</param>
        internal PlaylistApi(Lastfm lastfmApi)
        {
            this.lastfmApi = lastfmApi;
        }

        /// <summary>
        /// Add a track to a Last.fm user's playlist 
        /// This service requires authentication. 
        /// </summary>
        /// <param name="playlistID">The ID of the playlist - this is available in user.getPlaylists.</param>
        /// <param name="track">The track name to add to the playlist</param>
        /// <param name="artist">The artist name that corresponds to the track to be added.</param>
        public void AddTrack(int playlistID, string track, string artist)
        {
            if (!this.lastfmApi.Session.Authenticated)
            {
                throw new LastfmNetException("This service requires authentication.");
            }

            LastfmParameters parameters = new LastfmParameters("playlist.addTrack");
            parameters["playlistID"] = playlistID.ToString(CultureInfo.InvariantCulture);
            parameters["track"] = track.ToString(CultureInfo.InvariantCulture);
            parameters["artist"] = artist.ToString(CultureInfo.InvariantCulture);
            parameters.AddApiKey(this.lastfmApi.Session.ApiKey);
            parameters.AddSessionKey(this.lastfmApi.Session.SessionKey);
            parameters.Sign(this.lastfmApi.Session.ApiSecret);
            try
            {
                this.lastfmApi.MakeRequest(parameters, HttpMethod.Post);
            }
            catch (Exception ex)
            {
                throw new LastfmNetException("Unable to add the track! (" + ex.Message + ")", ex);
            }
        }

        /// <summary>
        /// Create a Last.fm playlist on behalf of a user 
        /// This service requires authentication. 
        /// </summary>
        /// <param name="title">Title for the playlist</param>
        /// <param name="description">Description for the playlist</param>
        /// <returns>A Last.fm playlist on behalf of a user </returns>
        public LastfmNet.Models.Playlist Create(string title = null, string description = null)
        {
            if (!this.lastfmApi.Session.Authenticated)
            {
                throw new LastfmNetException("This service requires authentication.");
            }

            LastfmParameters parameters = new LastfmParameters("playlist.create");
            if (title != null)
            {
                parameters["title"] = title;
            }

            if (description != null)
            {
                parameters["description"] = description;
            }

            parameters.AddApiKey(this.lastfmApi.Session.ApiKey);
            parameters.AddSessionKey(this.lastfmApi.Session.SessionKey);
            parameters.Sign(this.lastfmApi.Session.ApiSecret);
            try
            {
                LastfmResponse result = this.lastfmApi.MakeRequest(parameters, HttpMethod.Post);
                return new LastfmNet.Models.Playlist(result.MainNode);
            }
            catch (Exception ex)
            {
                throw new LastfmNetException("Unable to create playlist! (" + ex.Message + ")", ex);
            }
        }

        /// <summary>
        /// Fetch XSPF playlists using a lastfm playlist url. 
        /// This service does not require authentication. 
        /// </summary>
        /// <param name="playlistURL">A lastfm protocol playlist url ('lastfm://playlist/...') . See http://www.last.fm/api/playlists for more information.</param>
        /// <returns>XSPF playlists</returns>
        public LastfmNet.Models.XSPFPlaylist Fetch(string playlistURL)
        {
            LastfmParameters parameters = new LastfmParameters("playlist.fetch");
            parameters["playlistURL"] = playlistURL.ToString(CultureInfo.InvariantCulture);
            parameters.AddApiKey(this.lastfmApi.Session.ApiKey);
            try
            {
                LastfmResponse result = this.lastfmApi.MakeRequest(parameters);
                return new LastfmNet.Models.XSPFPlaylist(result.MainNode);
            }
            catch (Exception ex)
            {
                throw new LastfmNetException("Unable to fetch the playlist! (" + ex.Message + ")", ex);
            }
        }
    }
}
